#include "GY_GraphicsCircleItem.h"
#include <QPen>
#include <QPainter>
#include <QDebug>

GY_GraphicsCircleItem::GY_GraphicsCircleItem(const QString &guid, QGraphicsItem *parent)
    :GY_BasicsGraphicsObject(guid,this,parent)
{
    //图元类型
    GY_Object::setUserData(GY_ENUM::ClassType,QVariant("Circle"));
    initializationPropertyInfo();
    updataPen();
    updataBrush();
    QPointF point1=m_PropertyInfoMap.value("point1").propertyValue.value<QPointF>();
    updatePath(point1);
    QMap<QVariant,QPointF> editPoints = {{"point1",point1}};
    this->setEditPointF(editPoints);
    this->setPen(QColor(Qt::green));
    this->setCenterPointF(m_PropertyInfoMap.value("Center").propertyValue.toPointF());
}

GY_GraphicsCircleItem::GY_GraphicsCircleItem(const QString &guid, qreal x, qreal y, qreal r, QGraphicsItem *parent)
    :GY_BasicsGraphicsObject(guid,this,parent)
{
    //图元类型
    GY_Object::setUserData(GY_ENUM::ClassType,QVariant("Circle"));
    initializationPropertyInfo();
    updataPen();
    updataBrush();
    QPointF point1(x+r,y);
    m_PropertyInfoMap["point1"].propertyValue=point1;
    m_PropertyInfoMap["Radius"].propertyValue = r;
    updatePath(point1);
    QMap<QVariant,QPointF> editPoints = {{"point1",point1}};
    this->setEditPointF(editPoints);
    QPointF position(x,y);
    m_PropertyInfoMap["Center"].propertyValue = position;
    this->setCenterPointF(position);
}

void GY_GraphicsCircleItem::initializationPropertyInfo()
{
    /*
     *LineStyle属性的数据
     * QVector<qreal>中index(0)是Qt::PenCapStyle、Qt::PenJoinStyle与Qt::PenStyle的组合,index(1)为线条粗细，之后是自定义钢笔样式的数据 */
    QVector<qreal> varStyle;
    int style = Qt::SquareCap|Qt::BevelJoin|Qt::CustomDashLine;
    varStyle<<style<<2<<3<<2<<4<<5<<6<<7;

    int gradientSpread = QGradient::PadSpread;//指定如何填充渐变之外的区域
    QColor colorStart = QColor(0,255,0);//开始颜色
    QColor colorStop = QColor(0,0,255);//结束颜色
    int gradientType = QGradient::LinearGradient;//指定渐变的类型
    QPointF pointFStart = QPointF(0,0);//开始的坐标或中心点坐标
    QPointF pointFStop = QPointF(1,1);//结束的坐标或径向梯度的焦点坐标
    qreal centerRadius = 100;//中心半径
    qreal focalRadius = 100;//径向梯度的焦点半径
    QVector<qreal> varGradientStyle;
    varGradientStyle<<gradientSpread<<colorStart.rgb()<<colorStop.rgb()<<gradientType<<pointFStart.x()
                   <<pointFStart.y()<<pointFStop.x()<<pointFStop.y()<<centerRadius<<focalRadius;

    //位置
    GY_PropertyInfo positonPropertyInfo(this);
    positonPropertyInfo.propertyName="Center";
    positonPropertyInfo.propertyValue=QPointF(0,0);
    positonPropertyInfo.updateType = MoveUpdate|PointOfRelative|Update;
    positonPropertyInfo.propertyType = PointPropertyType;
    positonPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateCirlePoint;
    m_PropertyInfoMap.insert(positonPropertyInfo.propertyName,positonPropertyInfo);
    m_PropertyInfoMap[positonPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo point1PropertyInfo(this);
    point1PropertyInfo.propertyName="point1";
    point1PropertyInfo.propertyValue=QPointF(100,100);
    point1PropertyInfo.updateType = NotUpdate;
    point1PropertyInfo.propertyType = PointPropertyType;
    point1PropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updatePoint;
    m_PropertyInfoMap.insert("point1",point1PropertyInfo);
    m_PropertyInfoMap[point1PropertyInfo.propertyName].setConnect();

    GY_PropertyInfo radiusPropertyInfo(this);
    radiusPropertyInfo.propertyName="Radius";
    radiusPropertyInfo.propertyValue=100.0;
    radiusPropertyInfo.propertyType = DoublePropertyType;
    radiusPropertyInfo.updateType = Update|OrdinaryAttributes;
    radiusPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateRadius;
    m_PropertyInfoMap.insert(radiusPropertyInfo.propertyName,radiusPropertyInfo);
    m_PropertyInfoMap[radiusPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo ObjectName(this);
    ObjectName.propertyName = "ObjectName";
    ObjectName.propertyValue = QString();
    ObjectName.updateType = Update|OrdinaryAttributes;
    ObjectName.propertyType = QStringPropertyType;
    ObjectName.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateObjectName;
    m_PropertyInfoMap.insert("ObjectName",ObjectName);
    m_PropertyInfoMap[ObjectName.propertyName].setConnect();

    GY_PropertyInfo IsOutLined(this);
    IsOutLined.propertyName = "IsOutlined";
    IsOutLined.propertyValue = true;
    IsOutLined.updateType = Update|OrdinaryAttributes;
    IsOutLined.propertyType = BoolPropertyType;
    IsOutLined.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateIsOutLined;
    m_PropertyInfoMap.insert("IsOutlined",IsOutLined);
    m_PropertyInfoMap[IsOutLined.propertyName].setConnect();

    GY_PropertyInfo IsFilled(this);
    IsFilled.propertyName = "IsFilled";
    IsFilled.propertyValue = true;
    IsFilled.updateType = Update|OrdinaryAttributes;
    IsFilled.propertyType = BoolPropertyType;
    IsFilled.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateIsFilled;
    m_PropertyInfoMap.insert("IsFilled",IsFilled);
    m_PropertyInfoMap[IsFilled.propertyName].setConnect();

    GY_PropertyInfo IsAntialiased(this);
    IsAntialiased.propertyName = "IsAntialiased";
    IsAntialiased.propertyValue = false;
    IsAntialiased.updateType = Update|OrdinaryAttributes;
    IsAntialiased.propertyType = BoolPropertyType;
    IsAntialiased.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateIsAntialiased;
    m_PropertyInfoMap.insert("IsAntialiased",IsAntialiased);
    m_PropertyInfoMap[IsAntialiased.propertyName].setConnect();

    GY_PropertyInfo FillAttributes(this);
    FillAttributes.propertyName = "FillAttributes";
    FillAttributes.propertyValue = false;
    FillAttributes.propertyType = BoolPropertyType;
    FillAttributes.updateType = Update|OrdinaryAttributes;
    FillAttributes.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateFillAttributes;
    m_PropertyInfoMap.insert("FillAttributes",FillAttributes);
    m_PropertyInfoMap[FillAttributes.propertyName].setConnect();

    GY_PropertyInfo FillGradient(this);
    FillGradient.propertyName = "FillGradient";
    FillGradient.propertyValue = QVariant();
    FillGradient.updateType = Update|OrdinaryAttributes;
    FillGradient.propertyType = FillGradientPropertyType;
    FillGradient.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateFillGradient;
    m_PropertyInfoMap.insert("FillGradient",FillGradient);
    m_PropertyInfoMap[FillGradient.propertyName].setConnect();

    GY_PropertyInfo FillColor(this);
    FillColor.propertyName = "FillColor";
    FillColor.propertyValue = QColor();
    FillColor.updateType = Update|OrdinaryAttributes;
    FillColor.propertyType = ColorPropertyType;
    FillColor.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateFillColor;
    m_PropertyInfoMap.insert("FillColor",FillColor);
    m_PropertyInfoMap[FillColor.propertyName].setConnect();

    GY_PropertyInfo FillStyle(this);
    FillStyle.propertyName = "FillStyle";
    FillStyle.propertyValue = true;
    FillStyle.updateType = Update|OrdinaryAttributes;
    FillStyle.propertyType = BoolPropertyType;
    FillStyle.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateFillStyle;
    m_PropertyInfoMap.insert("FillStyle",FillStyle);
    m_PropertyInfoMap[FillStyle.propertyName].setConnect();

    GY_PropertyInfo PenColor(this);
    PenColor.propertyName = "PenColor";
    PenColor.propertyValue = QColor();
    PenColor.updateType = Update|OrdinaryAttributes;
    PenColor.propertyType = ColorPropertyType;
    PenColor.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updatePenColor;
    m_PropertyInfoMap.insert("PenColor",PenColor);
    m_PropertyInfoMap[PenColor.propertyName].setConnect();

    GY_PropertyInfo PenAttributes(this);
    PenAttributes.propertyName = "PenAttributes";
    PenAttributes.propertyValue = false;
    PenAttributes.updateType = Update|OrdinaryAttributes;
    PenAttributes.propertyType = BoolPropertyType;
    PenAttributes.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updatePenAttributes;
    m_PropertyInfoMap.insert("PenAttributes",PenAttributes);
    m_PropertyInfoMap[PenAttributes.propertyName].setConnect();

    GY_PropertyInfo FillOpacity(this);
    FillOpacity.propertyName = "FillOpacity";
    FillOpacity.propertyValue = 1;
    FillOpacity.updateType = Update|OrdinaryAttributes;
    FillOpacity.propertyType = QrealPropertyType;
    FillOpacity.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateFillOpacity;
    m_PropertyInfoMap.insert("FillOpacity",FillOpacity);
    m_PropertyInfoMap[FillOpacity.propertyName].setConnect();

    //Pattern填充图案数据
    QVector<QPoint> points;
    points << QPoint(0,1)<< QPoint(2,1)<< QPoint(3,1) << QPoint(5,1)<< QPoint(5,15) << QPoint(14,8);
    GY_PropertyInfo Pattern(this);
    Pattern.propertyName = "Pattern";
//    Pattern.propertyValue = QVariant::fromValue(points);
    Pattern.propertyValue = QVariant();
    Pattern.updateType = Update|OrdinaryAttributes;
    Pattern.propertyType = PatternPropertyType;
    Pattern.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updatePattern;
    m_PropertyInfoMap.insert("Pattern",Pattern);
    m_PropertyInfoMap[Pattern.propertyName].setConnect();

    GY_PropertyInfo PenOpacity(this);
    PenOpacity.propertyName = "PenOpacity";
    PenOpacity.propertyValue = 1;
    PenOpacity.updateType = Update|OrdinaryAttributes;
    PenOpacity.propertyType = QrealPropertyType;
    PenOpacity.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updatePenOpacity;
    m_PropertyInfoMap.insert("PenOpacity",PenOpacity);
    m_PropertyInfoMap[PenOpacity.propertyName].setConnect();

    GY_PropertyInfo LineStyle(this);
    LineStyle.propertyName = "LineStyle";
//    LineStyle.propertyValue = QVariant::fromValue(varStyle);
    LineStyle.propertyValue = QVariant();
    LineStyle.updateType = Update|OrdinaryAttributes;
    LineStyle.propertyType = LineStylePropertyType;
    LineStyle.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateLineStyle;
    m_PropertyInfoMap.insert("LineStyle",LineStyle);
    m_PropertyInfoMap[LineStyle.propertyName].setConnect();

    GY_PropertyInfo IsVisible(this);
    IsVisible.propertyName = "IsVisible";
    IsVisible.propertyValue = true;
    IsVisible.updateType = Update|OrdinaryAttributes;
    IsVisible.propertyType = BoolPropertyType;
    IsVisible.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsCircleItem::updateIsVisible;
    m_PropertyInfoMap.insert("IsVisible",IsVisible);
    m_PropertyInfoMap[IsVisible.propertyName].setConnect();

}

bool GY_GraphicsCircleItem::updateCirlePoint(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QPointF>())
    {
        return false;
    }
    QPointF position;
    position = this->mapFromScene(value.toPointF());
    m_PropertyInfoMap[name].propertyValue=position;
    this->setCenterPointF(position);
    position.rx() += m_PropertyInfoMap.value("Radius").propertyValue.toReal();
    m_PropertyInfoMap["point1"].propertyValue=position;
    this->setEditPointF("point1",position);
    updatePath(position);
    return true;
}

void GY_GraphicsCircleItem::updatePath(const QPointF &point1)
{
    qreal r = m_PropertyInfoMap.value("Radius").propertyValue.toReal();
    QPainterPath path;
    path.addEllipse(point1.x() - 2*r,point1.y() - r,2*r,2*r);
    this->setPath(path);
}

bool GY_GraphicsCircleItem::updatePoint(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QPointF>())
    {
        return false;
    }
    //坐标系转换（重要）
    QPointF pf;
    pf = this->mapFromScene(value.toPointF());
    QMap<QVariant,QPointF> map = this->getEditPointF();
    QPointF point1 = map.value("point1");
    //根据编辑点名称对应修改的点
    if(name.endsWith("point1")){
        qreal addR = pf.x() - point1.x();
        qreal r = m_PropertyInfoMap["Radius"].propertyValue.toReal();
        m_PropertyInfoMap["Radius"].propertyValue = (addR+r);
        point1.setX(pf.x());
        map.insert("point1",point1);
        m_PropertyInfoMap["point1"].propertyValue=point1;
        updatePath(point1);
    }
    this->setEditPointF(map);
    return true;
}

bool GY_GraphicsCircleItem::updateRadius(const QString &name, const QVariant &value)
{
    if(!value.canConvert<double>())
    {
        return false;
    }
    qreal addR = value.toReal() - m_PropertyInfoMap[name].propertyValue.toReal();
    m_PropertyInfoMap[name].propertyValue = value;
    QPointF point1=m_PropertyInfoMap.value("point1").propertyValue.value<QPointF>();
    point1.rx() += addR;
    m_PropertyInfoMap["point1"].propertyValue=point1;
    QMap<QVariant,QPointF> editPoints = {{"point1",point1}};
    this->setEditPointF(editPoints);
    updatePath(point1);
    return true;
}
